<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>XHR和Promise | 上课讲义</title>
    <meta name="description" content="A VitePress site">
    <link rel="stylesheet" href="/tingweipeng/assets/style.f3d4564a.css">
    <link rel="modulepreload" href="/tingweipeng/assets/app.bfa3a24a.js">
    <link rel="modulepreload" href="/tingweipeng/assets/ajax_day03.md.585e2c65.lean.js">
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css">
  <script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@4.0/dist/fancybox.umd.js"></script>
  <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-f44a984a><!--[--><!--]--><!--[--><span tabindex="-1" data-v-151f2593></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-151f2593> Skip to content </a><!--]--><!----><header class="VPNav" data-v-f44a984a data-v-a50780ff><div class="VPNavBar has-sidebar" data-v-a50780ff data-v-6f1d18b5><div class="container" data-v-6f1d18b5><div class="VPNavBarTitle has-sidebar" data-v-6f1d18b5 data-v-d5925166><a class="title" href="/tingweipeng/" data-v-d5925166><!--[--><!--]--><!----><!--[-->上课讲义<!--]--><!--[--><!--]--></a></div><div class="content" data-v-6f1d18b5><!--[--><!--]--><!----><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-6f1d18b5 data-v-f83db6ba><span id="main-nav-aria-label" class="visually-hidden" data-v-f83db6ba>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/tingweipeng/webapis/" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->webapis<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/tingweipeng/js进阶/" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->js进阶<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/tingweipeng/ajax/" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->ajax<!--]--><!----></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/tingweipeng/vue基础/" data-v-f83db6ba data-v-47a2263e data-v-3c355974><!--[-->vue基础<!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-6f1d18b5 data-v-a3e7452b><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-a3e7452b data-v-481098f9 data-v-eba7420e><span class="check" data-v-eba7420e><span class="icon" data-v-eba7420e><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-481098f9><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-481098f9><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-6f1d18b5 data-v-e4361c82 data-v-6ffb57d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-6ffb57d3><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-6ffb57d3><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-6ffb57d3><div class="VPMenu" data-v-6ffb57d3 data-v-1c5d0cfc><!----><!--[--><!--[--><!----><div class="group" data-v-e4361c82><div class="item appearance" data-v-e4361c82><p class="label" data-v-e4361c82>Appearance</p><div class="appearance-action" data-v-e4361c82><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-e4361c82 data-v-481098f9 data-v-eba7420e><span class="check" data-v-eba7420e><span class="icon" data-v-eba7420e><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-481098f9><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-481098f9><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-6f1d18b5 data-v-e5dd9c1c><span class="container" data-v-e5dd9c1c><span class="top" data-v-e5dd9c1c></span><span class="middle" data-v-e5dd9c1c></span><span class="bottom" data-v-e5dd9c1c></span></span></button></div></div></div><!----></header><div class="VPLocalNav" data-v-f44a984a data-v-b6162a8b><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-b6162a8b><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-b6162a8b><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-b6162a8b>Menu</span></button><a class="top-link" href="#" data-v-b6162a8b> Return to top </a></div><aside class="VPSidebar" data-v-f44a984a data-v-a186aa16><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-a186aa16><span class="visually-hidden" id="sidebar-aria-label" data-v-a186aa16> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-a186aa16><section class="VPSidebarGroup" data-v-a186aa16 data-v-6e45c352><div class="title" data-v-6e45c352><h2 class="title-text" data-v-6e45c352>ajax</h2><div class="action" data-v-6e45c352><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-6e45c352><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-6e45c352><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-6e45c352><!--[--><!--[--><a class="VPLink link link" href="/tingweipeng/ajax/" style="padding-left:0px;" data-v-36b976d1 data-v-3c355974><!--[--><span class="link-text" data-v-36b976d1>01-初识ajax</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/tingweipeng/ajax/day02.html" style="padding-left:0px;" data-v-36b976d1 data-v-3c355974><!--[--><span class="link-text" data-v-36b976d1>02-表单提交</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link active" href="/tingweipeng/ajax/day03.html" style="padding-left:0px;" data-v-36b976d1 data-v-3c355974><!--[--><span class="link-text" data-v-36b976d1>03-xhr和promise</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/tingweipeng/ajax/day04.html" style="padding-left:0px;" data-v-36b976d1 data-v-3c355974><!--[--><span class="link-text" data-v-36b976d1>04-异步编程和事件循环</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-f44a984a data-v-d981fe29><div class="VPDoc has-sidebar has-aside" data-v-d981fe29 data-v-cfb513e0><div class="container" data-v-cfb513e0><div class="aside" data-v-cfb513e0><div class="aside-curtain" data-v-cfb513e0></div><div class="aside-container" data-v-cfb513e0><div class="aside-content" data-v-cfb513e0><div class="VPDocAside" data-v-cfb513e0 data-v-afc4c1a1><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-afc4c1a1 data-v-2865c0b0><div class="content" data-v-2865c0b0><div class="outline-marker" data-v-2865c0b0></div><div class="outline-title" data-v-2865c0b0>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-2865c0b0><span class="visually-hidden" id="doc-outline-aria-label" data-v-2865c0b0> Table of Contents for current page </span><ul class="root" data-v-2865c0b0 data-v-1188541a><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-afc4c1a1></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-cfb513e0><div class="content-container" data-v-cfb513e0><!--[--><!--]--><main class="main" data-v-cfb513e0><div style="position:relative;" class="vp-doc _tingweipeng_ajax_day03" data-v-cfb513e0><div><h1 id="xhr和promise" tabindex="-1">XHR和Promise <a class="header-anchor" href="#xhr和promise" aria-hidden="true">#</a></h1><h2 id="学习目标" tabindex="-1">学习目标 <a class="header-anchor" href="#学习目标" aria-hidden="true">#</a></h2><ol><li>了解原生Ajax语法</li><li>理解Promise的语法和回调地狱</li><li>案例-封装Ajax函数(了解)</li><li>案例-分类导航</li></ol><h2 id="ajax-原生学习" tabindex="-1">Ajax-原生学习 <a class="header-anchor" href="#ajax-原生学习" aria-hidden="true">#</a></h2><h3 id="目标" tabindex="-1">目标 <a class="header-anchor" href="#目标" aria-hidden="true">#</a></h3><p>了解原生JS如何编写和发送Ajax请求</p><h3 id="讲解" tabindex="-1">讲解 <a class="header-anchor" href="#讲解" aria-hidden="true">#</a></h3><p>Ajax是一个技术的名称, 而以前我们具体使用的是<code>axios.js</code>插件来发送请求 ，但是其实axios.js也是一个库, 内部是原生JS代码, 实际它是对原生的代码进行了封装。</p><p>今天我们就来解开神秘的面纱</p><p>Ajax如果用原生JS实现, 需要使用window对象提供的一个构造函数, 叫<code>XMLHttpRequest</code></p><h3 id="xmlhttprequest" tabindex="-1">XMLHttpRequest <a class="header-anchor" href="#xmlhttprequest" aria-hidden="true">#</a></h3><p>格式</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 1. 创建一个xhr对象</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2. 设置请求方式和请求地址</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(请求方式, 请求地址)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 3. 发送请求</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 4. 监听load（请求成功）事件 ==&gt; 可以获取响应数据</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">() {</span></span>
<span class="line"><span style="color:#C9D1D9;">	console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(xhr.response)  </span><span style="color:#8B949E;">// 服务器返回的数据</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h3 id="示例代码" tabindex="-1">示例代码 <a class="header-anchor" href="#示例代码" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 请求省份名字列表</span></span>
<span class="line"><span style="color:#8B949E;">// 接口地址: http://ajax-api.itheima.net/api/province</span></span>
<span class="line"><span style="color:#8B949E;">// 请求方式：GET</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 原生Ajax编写↓</span></span>
<span class="line"><span style="color:#8B949E;">// 1.创建一个xhr对象</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2.设置请求方式和请求地址 xhr.open(&quot;请求方式&quot;, &quot;请求地址&quot;)</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;GET&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/province&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 3.发送请求</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 4.监听load(请求成功)事件 ==&gt; 可以获取响应数据</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(xhr.response) </span><span style="color:#8B949E;">// 响应体数据</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 知识点: 把JSON格式字符串 ==&gt; 转成JS数据类型</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 语法: JSON.parse(JSON字符串)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 返回值: JS数据类型</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> result </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">parse</span><span style="color:#C9D1D9;">(xhr.response)</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(result);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h3 id="代码运行流程" tabindex="-1">代码运行流程 <a class="header-anchor" href="#代码运行流程" aria-hidden="true">#</a></h3><p><img src="/tingweipeng/assets/1668096369233-5eeaee25-0371-4b4b-8eaf-58d62e423720.d8a54ea4.png" alt="image.png" data-fancybox="gallery"></p><h3 id="小结" tabindex="-1">小结 <a class="header-anchor" href="#小结" aria-hidden="true">#</a></h3><ol><li>Ajax原理底层依靠一个构造函数是什么？ <details><summary>答案</summary><ul><li> XMLHttpRequest </li></ul></details></li></ol><h2 id="ajax-原生query传参" tabindex="-1">Ajax-原生query传参 <a class="header-anchor" href="#ajax-原生query传参" aria-hidden="true">#</a></h2><h3 id="目标-1" tabindex="-1">目标 <a class="header-anchor" href="#目标-1" aria-hidden="true">#</a></h3><p>了解Ajax原生传参使用</p><h3 id="讲解-1" tabindex="-1">讲解 <a class="header-anchor" href="#讲解-1" aria-hidden="true">#</a></h3><p>新建<code>Ajax_原生传参.html</code></p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 请求辽宁省下所有城市列表</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 复习: 之前说过query查询参数要携带在url?后面</span></span>
<span class="line"><span style="color:#8B949E;">// 格式: 参数名=值&amp;参数名=值</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;GET&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/city?pname=辽宁省`</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> result </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">parse</span><span style="color:#C9D1D9;">(xhr.response)</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(result);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h3 id="小结-1" tabindex="-1">小结 <a class="header-anchor" href="#小结-1" aria-hidden="true">#</a></h3><ol><li>原生Ajax如何传递查询参数? <details><summary>答案</summary><ul><li>在url?后面拼接查询参数 </li></ul></details></li></ol><h2 id="ajax-原生post" tabindex="-1">Ajax-原生POST <a class="header-anchor" href="#ajax-原生post" aria-hidden="true">#</a></h2><h3 id="目标-2" tabindex="-1">目标 <a class="header-anchor" href="#目标-2" aria-hidden="true">#</a></h3><p>了解原生POST请求和请求体使用</p><h3 id="格式" tabindex="-1">格式 <a class="header-anchor" href="#格式" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 1. 创建一个xhr对象</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2. 设置请求方式和请求地址</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(请求方式, 请求地址)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 3. 发送请求</span></span>
<span class="line"><span style="color:#8B949E;">// 请求体</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">(请求体)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 4. 监听load（请求成功）事件 ==&gt; 可以获取响应数据</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">() {</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(xhr.response)  </span><span style="color:#8B949E;">// 服务器返回的数据</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h3 id="示例代码-1" tabindex="-1">示例代码 <a class="header-anchor" href="#示例代码-1" aria-hidden="true">#</a></h3><p>新建<code>Ajax_原生POST.html</code>, 请求POST测试接口</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 测试POST请求</span></span>
<span class="line"><span style="color:#8B949E;">// 接口地址: http://ajax-api.itheima.net/api/data</span></span>
<span class="line"><span style="color:#8B949E;">// 请求方式: POST</span></span>
<span class="line"><span style="color:#8B949E;">// 参数随意</span></span>
<span class="line"></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;post&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/data&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 请求体要在这里携带</span></span>
<span class="line"><span style="color:#8B949E;">// 请求体支持三种内容类型, 用哪个还是要和后端对上</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;username=admin&amp;password=123456&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> result </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">parse</span><span style="color:#C9D1D9;">(xhr.response)</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(result);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><p>问题：发现后端并没有解析到我们的参数, 通过后台提示和Network检查, 我们请求头Content-Type的值不对</p><p>解决: 之前我们使用axios会自动携带Content-Type内容请求头, 而原生的ajax就需要自己携带啦!</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2. 需要携带请求头Content-Type和固定值指定传递的请求体内容类型, 让后端用对应方式解析</span></span>
<span class="line"><span style="color:#8B949E;">// 要注意: 在open后send前之间设置</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">setRequestHeader</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;Content-Type&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#A5D6FF;">&#39;application/json&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>落地完整代码</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 测试POST请求</span></span>
<span class="line"><span style="color:#8B949E;">// 接口地址: http://ajax-api.itheima.net/api/books</span></span>
<span class="line"><span style="color:#8B949E;">// 请求方式: POST</span></span>
<span class="line"><span style="color:#8B949E;">// 参数随意</span></span>
<span class="line"></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;POST&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/books`</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2. 需要携带请求头Content-Type和固定值指定传递的请求体内容类型, 让后端用对应方式解析</span></span>
<span class="line"><span style="color:#8B949E;">// 要注意: 在open后send前之间设置</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">setRequestHeader</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;Content-Type&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#A5D6FF;">&#39;application/json&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 1. 请求体要在这里携带</span></span>
<span class="line"><span style="color:#8B949E;">// 请求体支持三种内容类型, 用哪个还是要和后端对上</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">stringify</span><span style="color:#C9D1D9;">({</span></span>
<span class="line"><span style="color:#C9D1D9;">    bookname: </span><span style="color:#A5D6FF;">&#39;黑马&#39;</span><span style="color:#C9D1D9;">,</span></span>
<span class="line"><span style="color:#C9D1D9;">    author: </span><span style="color:#A5D6FF;">&#39;老李&#39;</span><span style="color:#C9D1D9;">,</span></span>
<span class="line"><span style="color:#C9D1D9;">    publisher: </span><span style="color:#A5D6FF;">&#39;黑马出版社&#39;</span></span>
<span class="line"><span style="color:#C9D1D9;">}))</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> result </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">parse</span><span style="color:#C9D1D9;">(xhr.response)</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(result);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br></div></div><h3 id="小结-2" tabindex="-1">小结 <a class="header-anchor" href="#小结-2" aria-hidden="true">#</a></h3><ol><li><p>请求体内容类型有哪三种?</p><details><summary>答案</summary><ul><li> 键值对字符串 </li><li> JSON字符串 </li><li> 表单数据FormData </li></ul></details></li><li><p>使用axios时，自带了请求头的类型</p></li></ol><h2 id="概念-同步异步" tabindex="-1">概念-同步异步 <a class="header-anchor" href="#概念-同步异步" aria-hidden="true">#</a></h2><h3 id="目标-3" tabindex="-1">目标 <a class="header-anchor" href="#目标-3" aria-hidden="true">#</a></h3><ul><li>掌握哪些是同步代码</li><li>掌握哪些是异步代码</li></ul><h3 id="请说出下面代码的输出结果" tabindex="-1">请说出下面代码的输出结果 <a class="header-anchor" href="#请说出下面代码的输出结果" aria-hidden="true">#</a></h3><div class="language-html line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki"><code><span class="line"><span style="color:#C9D1D9;">  &lt;</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">      console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">1000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">3</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">  &lt;/</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>结果：</p><div class="language-text line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki"><code><span class="line"><span style="color:#c9d1d9;"></span></span>
<span class="line"><span style="color:#c9d1d9;"></span></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>下面代码输出的结果是</p><div class="language-html line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki"><code><span class="line"><span style="color:#C9D1D9;">&lt;</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">src</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js&quot;</span><span style="color:#C9D1D9;">&gt;&lt;/</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">&lt;</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">if</span><span style="color:#C9D1D9;"> (</span><span style="color:#79C0FF;">true</span><span style="color:#C9D1D9;">) {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    } </span><span style="color:#FF7B72;">else</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">3</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    }</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">4</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">1000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">const</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">fn</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> () </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">5</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    }</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">for</span><span style="color:#C9D1D9;"> (</span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> i </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">; i </span><span style="color:#FF7B72;">&lt;</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">3</span><span style="color:#C9D1D9;">; i</span><span style="color:#FF7B72;">++</span><span style="color:#C9D1D9;">) {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">6</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    }   </span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">7</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">fn</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"><span style="color:#C9D1D9;">    document.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;click&#39;</span><span style="color:#C9D1D9;">, () </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">8</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">axios</span><span style="color:#C9D1D9;">({</span></span>
<span class="line"><span style="color:#C9D1D9;">        url: </span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/province&#39;</span><span style="color:#C9D1D9;">,</span></span>
<span class="line"><span style="color:#C9D1D9;">        method: </span><span style="color:#A5D6FF;">&#39;GET&#39;</span></span>
<span class="line"><span style="color:#C9D1D9;">    }).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">9</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">10</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">&lt;/</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br></div></div><ol start="2"><li>打印的结果是</li></ol><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">2</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">666</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">7</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">5</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">10</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">9</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">4</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h3 id="同步和异步" tabindex="-1">同步和异步 <a class="header-anchor" href="#同步和异步" aria-hidden="true">#</a></h3><p>同步代码： 执行顺序和书写顺序一致</p><p>异步代码: 不是立即执行的，执行顺序和书写顺序不一致。</p><p>js中典型的异步代码有：</p><ul><li>定时器：setTimeout，setInterval</li><li>Ajax</li><li>dom事件</li></ul><h3 id="小结-3" tabindex="-1">小结 <a class="header-anchor" href="#小结-3" aria-hidden="true">#</a></h3><ol><li>JS中都有哪些异步代码? <details><summary>答案</summary><ul><li> 定时器, Ajax, 事件 </li></ul></details></li></ol><h2 id="概念-回调函数" tabindex="-1">概念-回调函数 <a class="header-anchor" href="#概念-回调函数" aria-hidden="true">#</a></h2><h3 id="目标-4" tabindex="-1">目标 <a class="header-anchor" href="#目标-4" aria-hidden="true">#</a></h3><p>掌握回调函数的使用和执行过程，理解它和异步的关系</p><h3 id="现象" tabindex="-1">现象 <a class="header-anchor" href="#现象" aria-hidden="true">#</a></h3><p>发现前面异步的代码, 都有一个函数体, 这个函数体里代码都是等待这个异步任务有结果后执行</p><p><img src="/tingweipeng/assets/1668096488149-2657c361-b681-494e-8928-b679e5b77cd9.4d908c61.png" alt="image.png" data-fancybox="gallery"></p><h3 id="回调函数" tabindex="-1">回调函数 <a class="header-anchor" href="#回调函数" aria-hidden="true">#</a></h3><p>是自己定义的函数，但不是自己调用的</p><p>典型特点：把一个函数当成实参传递, 将来特定的时机调用, 这个函数体就叫回调函数 。</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">theFn</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">fn</span><span style="color:#C9D1D9;">) { </span><span style="color:#8B949E;">// fn = () =&gt; { console.log(&#39;回调函数执行&#39;) }</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">fn</span><span style="color:#C9D1D9;">() </span><span style="color:#8B949E;">// 代码执行到这句话, 会回调theFn()里函数体执行, 这个过程就叫回调函数</span></span>
<span class="line"><span style="color:#C9D1D9;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D2A8FF;">theFn</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> { </span><span style="color:#8B949E;">// 此箭头函数体作为实参值传递给了thenFn的形参变量fn上</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;回调函数执行&#39;</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 小结: 所以以后在调用一个函数时, 把函数体作为实参值传入到另一个函数内, 它应该就是一个回调函数应用了</span></span>
<span class="line"><span style="color:#8B949E;">// 例如forEach等数组方法都是回调函数的运行, 还有我们所有的异步任务都有回调函数的应用</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>我们之前接触的回调函数</p><ol><li><code>forEach</code>, <code>map</code>, <code>filter</code>.....</li><li><code>addEventlistener(&#39;click&#39;, () =&gt; {} )</code></li></ol><h3 id="小结-4" tabindex="-1">小结 <a class="header-anchor" href="#小结-4" aria-hidden="true">#</a></h3><ol><li>什么是回调函数? <details><summary>答案</summary><ul><li> 把一个函数当做实参传递, 将来特定的时机调用, 这个函数体就叫回调函数 </li></ul></details></li></ol><h2 id="概念-回调地狱" tabindex="-1">概念-回调地狱 <a class="header-anchor" href="#概念-回调地狱" aria-hidden="true">#</a></h2><h3 id="目标-5" tabindex="-1">目标 <a class="header-anchor" href="#目标-5" aria-hidden="true">#</a></h3><p>理解的回调地狱的概念</p><h3 id="示例" tabindex="-1">示例 <a class="header-anchor" href="#示例" aria-hidden="true">#</a></h3><p>调用接口，请求第6个省的第1个市下的地区列表</p><p>特点：</p><ol><li>发多次ajax请求</li><li>后一次请求要依赖上一次请求的结果</li></ol><p>这里我们以一个, 请求省市区列表, 最终获取地区列表为例,  来体验下回调地狱, 直接复制代码查看</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 获取所有省市区数据, 随便获取</span></span>
<span class="line"><span style="color:#8B949E;">// 1. 获取所有省份列表</span></span>
<span class="line"><span style="color:#C9D1D9;">axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/province&#39;</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 2. 获取某个省, 对应的城市列表</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> pname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.data[</span><span style="color:#79C0FF;">5</span><span style="color:#C9D1D9;">];</span></span>
<span class="line"><span style="color:#C9D1D9;">    axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/city?pname=${</span><span style="color:#C9D1D9;">pname</span><span style="color:#A5D6FF;">}`</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 3. 获取某个市, 对应的地区列表</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> cname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.data[</span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">]</span></span>
<span class="line"><span style="color:#C9D1D9;">        axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/area?pname=${</span><span style="color:#C9D1D9;">pname</span><span style="color:#A5D6FF;">}&amp;cname=${</span><span style="color:#C9D1D9;">cname</span><span style="color:#A5D6FF;">}`</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">        })</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>上面的代码就出现了回调地狱 概念: 在回调函数内, 再嵌套回调函数, 一直嵌套下去形成了回调地狱</p><h3 id="小结-5" tabindex="-1">小结 <a class="header-anchor" href="#小结-5" aria-hidden="true">#</a></h3><ol><li>什么是回调地狱? <details><summary>答案</summary><ul><li> 在回调函数内, 再嵌套回调函数, 一直嵌套下去形成了回调地狱 </li></ul></details></li></ol><h2 id="promise-基本语法" tabindex="-1">Promise-基本语法 <a class="header-anchor" href="#promise-基本语法" aria-hidden="true">#</a></h2><h3 id="目标-6" tabindex="-1">目标 <a class="header-anchor" href="#目标-6" aria-hidden="true">#</a></h3><p>掌握Promise相关语法使用</p><h3 id="promise" tabindex="-1">Promise <a class="header-anchor" href="#promise" aria-hidden="true">#</a></h3><p>它是一个ES6提出一个新语法，用来<strong>优化异步代码的写法</strong>。</p><ul><li>在前端领域是我们必须要会的一个内容</li><li>后续的课程中也会多次使用</li></ul><p>promise：承诺。</p><ul><li><p>生活中.它是用来表述 对将来要发生的事情的肯定。 例如 ： 高中生说，老师，我会考上一所好大学的；销售员说，老板，我一定会签下大单的；程序员说，老妈，我过年一定会带个女朋友回来的。</p></li><li><p>在ES6中，它是新增的构造器（Array, Object, Promise），用来优化实现异步操作。在没有它之前，javascript中的异步处理，大多是利用回调函数来实现的。典型的几种如下</p><p>（1）setTimeout</p><p>（2）ajax 现在有了promise，就可以对这些异步操作进行改写了。</p></li></ul><h3 id="经典格式" tabindex="-1">经典格式 <a class="header-anchor" href="#经典格式" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// resolve和reject是Promise内提供的2个函数, 用于回调返回结果到外面</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(成功结果) </span><span style="color:#8B949E;">// 触发.then()小括号里函数体执行</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(失败结果) </span><span style="color:#8B949E;">// 触发.catch()小括号里函数体执行</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">成功结果变量名</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">失败结果变量名</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">finally</span><span style="color:#C9D1D9;">(()</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">   </span><span style="color:#8B949E;">// 一定会执行的代码</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><ul><li><code>resolve</code>函数的作用是，将Promise对象的状态从“未完成”变为“成功”，触发.then的执行</li><li><code>reject</code>函数的作用是，将Promise对象的状态从“未完成”变为“失败”，触发.catch的执行</li></ul><h3 id="示例代码-2" tabindex="-1">示例代码 <a class="header-anchor" href="#示例代码-2" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 语法:</span></span>
<span class="line"><span style="color:#8B949E;">/*</span></span>
<span class="line"><span style="color:#8B949E;">    let Promise对象变量名 = new Promise((resolve, reject) =&gt; {</span></span>
<span class="line"><span style="color:#8B949E;">        // resolve和reject是Promise内提供的2个函数, 用于回调返回结果到外面</span></span>
<span class="line"><span style="color:#8B949E;">        resolve(成功结果) // 触发.then()小括号里函数体执行</span></span>
<span class="line"><span style="color:#8B949E;">        reject(失败结果) // 触发.catch()小括号里函数体执行</span></span>
<span class="line"><span style="color:#8B949E;">    })</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">    Promise对象变量名.then((成功结果变量名) =&gt; {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">    }).catch((失败结果变量名) =&gt; {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">    })</span></span>
<span class="line"><span style="color:#8B949E;">*/</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// resolve和reject是Promise内提供的2个函数, 用于回调返回结果到外面</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// resolve(&#39;成功了&#39;)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;失败了&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res)</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">error</span><span style="color:#C9D1D9;">(err)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br></div></div><h3 id="图示" tabindex="-1">图示 <a class="header-anchor" href="#图示" aria-hidden="true">#</a></h3><p><img src="/tingweipeng/assets/1668347417670-e67620d2-2ccf-4d05-ad02-691378cbc7f6.3175a72c.jpeg" alt="" data-fancybox="gallery"></p><p><img src="https://cdn.nlark.com/yuque/0/2022/jpeg/762958/1668347529627-8db882df-cea5-445c-b82a-a4a651b4ef3a.jpeg" alt="" data-fancybox="gallery"></p><h3 id="小结-6" tabindex="-1">小结 <a class="header-anchor" href="#小结-6" aria-hidden="true">#</a></h3><ol><li>new 一个 Promise的格式是? <details><summary>答案</summary><ul><li>const p = new Promise((resolve, reject)=&gt;{}) </li><li>p.then().catch().finally() </li></ul></details></li><li>对象内的resolve和reject函数作用? <details><summary>答案</summary><ul><li>回调外部的then/catch, 传递成功/失败的动作和结果 </li></ul></details></li></ol><h2 id="promise-三种状态和值" tabindex="-1">Promise-三种状态和值 <a class="header-anchor" href="#promise-三种状态和值" aria-hidden="true">#</a></h2><h3 id="目标-7" tabindex="-1">目标 <a class="header-anchor" href="#目标-7" aria-hidden="true">#</a></h3><p>掌握Promise的三种状态和值</p><h3 id="三种状态" tabindex="-1">三种状态 <a class="header-anchor" href="#三种状态" aria-hidden="true">#</a></h3><p>pending: 准备； resolved(或者fulfilled) 成功； rejected： 失败</p><p>准备：new实例化后, Promise对象(pending准备状态)</p><p>成功：当Promise内代码执行了resolve, 会导致所在的Promise对象 变成 fulfilled成功状态</p><p>失败：当Promise内代码执行了reject, 会导致所在的Promise对象 变成 rejected失败状态</p><p><img src="/tingweipeng/assets/1668096580009-c7ac6fa4-75fd-4dec-872a-d1716ede4308.529de1a4.png" alt="image.png" data-fancybox="gallery"> 状态的变化不可逆</p><h3 id="值" tabindex="-1">值 <a class="header-anchor" href="#值" aria-hidden="true">#</a></h3><p>resolve(值)，这个值会自动传递给then</p><p>reject(值)，这个值会自动传递给catch</p><h3 id="示例代码-3" tabindex="-1">示例代码 <a class="header-anchor" href="#示例代码-3" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 1. 创建Promise对象并返回此对象在原地, 并立刻执行函数内代码, 交给浏览器去做倒计时了(异步, 不会阻塞主线程代码往下走, 所以继续走2)</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 3. 等2秒后, resolve触发, 影响p对象状态</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功结果&#39;</span><span style="color:#C9D1D9;">) </span><span style="color:#8B949E;">// resolve =&gt; fulfilled状态 =&gt; .then</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// reject(&#39;失败结果&#39;) // reject =&gt; rejected状态 =&gt; .catch</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2. 立刻给p对象添加.then函数并传入函数体等待被调用接收成功结果(此是.then()小括号里函数体不会执行)</span></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res); </span><span style="color:#8B949E;">// 2秒后返回&#39;成功结果&#39;</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">error</span><span style="color:#C9D1D9;">(err)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><h3 id="小结-7" tabindex="-1">小结 <a class="header-anchor" href="#小结-7" aria-hidden="true">#</a></h3><ol><li><p>Promise对象有几种状态？</p><details><summary>答案</summary><ul><li> pending</li><li> fulfilled </li><li> rejected </li></ul></details></li><li><p>Promise对象的状态如何切换?</p><details><summary>答案</summary><ul><li> 刚创建会立刻执行new Promise函数内代码, 此时为pending准备状态</li><li> 当Promise对象内异步代码有结果触发resolve, 会导致Promise对象状态为fulfilled兑现成功状态 </li><li> 当Promise对象内异步代码有结果触发reject, 会导致Promise对象状态为rejected失败状态, 拒绝兑现承诺 </li></ul></details></li></ol><h2 id="使用promise改造回调函数" tabindex="-1">使用Promise改造回调函数 <a class="header-anchor" href="#使用promise改造回调函数" aria-hidden="true">#</a></h2><p>下面我们回到具体的问题：如何对现有的，通过回调函数来实现异步操作的代码进行改写。</p><h3 id="基本套路" tabindex="-1">基本套路 <a class="header-anchor" href="#基本套路" aria-hidden="true">#</a></h3><p>第一步：建立模板函数。这里的模板函数是指固定的套路：写一个空函数，在函数体中new 一个promise对象，并返回。</p><p>第二步：把异步功能写入构造函数中，根据实际来决定是否调用resolve,reject。</p><p>第三步：调用函数。通过fnName().then().catch() 结构来调用这个函数。</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">fnName</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">const</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">p</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{})</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> p;</span></span>
<span class="line"><span style="color:#C9D1D9;">}</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h3 id="示例-ajax原回调函数的写法" tabindex="-1">示例: ajax原回调函数的写法 <a class="header-anchor" href="#示例-ajax原回调函数的写法" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">();</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;get&#39;</span><span style="color:#C9D1D9;">,</span><span style="color:#A5D6FF;">&#39;http://httpbin.org/ip&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(xhr.response) </span><span style="color:#8B949E;">// 响应体数据</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 知识点: 把JSON格式字符串 ==&gt; 转成JS数据类型</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 语法: JSON.parse(JSON字符串)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 返回值: JS数据类型</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> result </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">parse</span><span style="color:#C9D1D9;">(xhr.response)</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(result);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#C9D1D9;">xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h3 id="改写之后" tabindex="-1">改写之后 <a class="header-anchor" href="#改写之后" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">ajax</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">() {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">();</span></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;get&#39;</span><span style="color:#C9D1D9;">,</span><span style="color:#A5D6FF;">&#39;http://httpbin.org/ip&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">onload</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">() {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(xhr.responseText)</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">onerror</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> (){</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;请求接口错误&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">}</span></span>
<span class="line"><span style="color:#D2A8FF;">ajax</span><span style="color:#C9D1D9;">().</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res)</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(err)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h2 id="小小一道面试题" tabindex="-1">小小一道面试题 <a class="header-anchor" href="#小小一道面试题" aria-hidden="true">#</a></h2><h3 id="目标-8" tabindex="-1">目标 <a class="header-anchor" href="#目标-8" aria-hidden="true">#</a></h3><p>让sleep 的功能与setTimeout一样：就是等2000毫秒之后再执行then中的回调函数</p><p>代码填空，并完成指定功能。</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">sleep</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">time</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 请写出你的代码</span></span>
<span class="line"><span style="color:#C9D1D9;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D2A8FF;">sleep</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(()</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;后续操作&quot;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>参考代码如下：</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">sleep</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">time</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 请写出你的代码</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"><span style="color:#C9D1D9;">        }, time)</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">}</span></span>
<span class="line"></span>
<span class="line"><span style="color:#D2A8FF;">sleep</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(()</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;后续操作&quot;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h2 id="then的格式及执行逻辑" tabindex="-1">then的格式及执行逻辑 <a class="header-anchor" href="#then的格式及执行逻辑" aria-hidden="true">#</a></h2><h3 id="目标-9" tabindex="-1">目标 <a class="header-anchor" href="#目标-9" aria-hidden="true">#</a></h3><p>掌握then方法的使用；</p><h3 id="作用" tabindex="-1">作用 <a class="header-anchor" href="#作用" aria-hidden="true">#</a></h3><p>then方法的作用是为Promise对象添加<strong>状态改变</strong>时的回调函数。 下面从其调用格式，执行逻辑及返回值三个方面来介绍</p><h3 id="then的调用格式" tabindex="-1">then的调用格式 <a class="header-anchor" href="#then的调用格式" aria-hidden="true">#</a></h3><p>它有两个参数，每个参数都是函数。 第二个参数是可选的。 如下：</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// p 是一个promise对象</span></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(函数1[,函数2])</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>它的两个参数都是函数。</p><ul><li>第一个参数是resolved状态的回调函数。当p的状态从pending变成了resolved，函数1会执行。</li><li>第二个参数是rejected状态的回调函数。 当p的状态从pending变成了rejected，函数2会执行。</li></ul><p>其中第二个参数是可选的，如果只写一个参数的话就是如下: promise对象.then(函数1)</p><h3 id="执行逻辑" tabindex="-1">执行逻辑 <a class="header-anchor" href="#执行逻辑" aria-hidden="true">#</a></h3><p>以如下代码为例</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">                    </span><span style="color:#8B949E;">//  resolve(&#39;val1&#39;);</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;val2&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FFA657;">okVal</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">info</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;成功&quot;</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">     console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(okVal);</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span></span>
<span class="line"><span style="color:#C9D1D9;"> </span><span style="color:#FFA657;">errVal</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">     console.</span><span style="color:#D2A8FF;">info</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;失败&quot;</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">     console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(errVal);</span></span>
<span class="line"><span style="color:#C9D1D9;">    }</span></span>
<span class="line"><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>它的两个参数都是函数，其执行逻辑是:</p><ul><li>如果promise对象的状态是resolved，则then()会执行第一个函数，并传入当前的PromiseValue（即上面的val1）;</li><li>如果promise对象的状态是rejected，则then()会执行第二个函数，并传入当前的PromiseValue（即上面的val2）;</li><li>特别地，如果promise对象的状态是rejected，且此时then方法并没有设置第二个参数，就会向外抛出一个错误，错误的提示大约是Uncaught (in promise)。</li></ul><p>如下是图示 <img src="/tingweipeng/assets/1668345447743-eeba4227-8465-4bc4-9c33-886ba6f0e684.25f080b5.png" alt="image.png" data-fancybox="gallery"></p><h4 id="示例代码1" tabindex="-1">示例代码1 <a class="header-anchor" href="#示例代码1" aria-hidden="true">#</a></h4><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">)</span><span style="color:#8B949E;">//主动调用resolve，并传入</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#8B949E;">// 此时，P的状态是resolved，且值promiseValue 是1.</span></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 因为p的状态是resolved，所以自动执行then的第一个参数，并且把promisevalue传进来。</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;then,ok&quot;</span><span style="color:#C9D1D9;">,res)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p>执行输出结果是：then,ok,1</p><h4 id="示例代码2" tabindex="-1">示例代码2 <a class="header-anchor" href="#示例代码2" aria-hidden="true">#</a></h4><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">2</span><span style="color:#C9D1D9;">)</span><span style="color:#8B949E;">//主动调用reject，并传入实参</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#8B949E;">// 此时，P的状态是rejected，且值promiseValue 是2.</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 因为p的状态是resolved，所以这句代码不会执行。</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;then,ok&quot;</span><span style="color:#C9D1D9;">,res)</span></span>
<span class="line"><span style="color:#C9D1D9;">},(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 因为p的状态是rejected，所以自动执行then的第二个参数，并且把promisevalue传进来。</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;then,err&quot;</span><span style="color:#C9D1D9;">,err)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>执行输出结果是：then,err,2</p><h2 id="then的返回值-难点" tabindex="-1">then的返回值(难点) <a class="header-anchor" href="#then的返回值-难点" aria-hidden="true">#</a></h2><p>then()方法的返回值也是一个Promise对象，但是要注意的是它的返回值是一个新的Promise对象，与调用then方法的并<strong>不是同一个对象</strong>。</p><p>看如下代码：</p><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">(()</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(){}); </span></span>
<span class="line"><span style="color:#8B949E;">// p2也是一个promise对象。</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(p1 </span><span style="color:#FF7B72;">===</span><span style="color:#C9D1D9;"> p2); </span><span style="color:#8B949E;">// false</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>如上代码可以说明p1.then()的结果是一个与p1不同的promise对象。</p><p>换句话说，then()会封装一个全新的promise对象p2。</p><p>那既然 p2也是一个promise对象，那么，p2的状态（promiseStatus）和值(promiseValue)分别是什么？</p><h3 id="p2的状态及promisevalue如何确定" tabindex="-1">p2的状态及PromiseValue如何确定？ <a class="header-anchor" href="#p2的状态及promisevalue如何确定" aria-hidden="true">#</a></h3><p>p2的状态及promiseValue按如下规则来确定</p><ul><li>如果p1的状态是pending,则p2的状态也是pending。</li><li>如果p1的状态是resolved，then()会去执行f_ok，则p2的状态由f_ok的返回值决定。 <ul><li>如果f_ok返回值不是Promise对象，则p2的状态是resolved，且p2的promiseValue就是f_ok函数的return值。</li><li>如果f_ok返回值是一个Promise对象，则p2的状态及promiseValue以这个Promise对象为准。</li><li>如果f_ok这个函数内部发生了错误（或者是用户主动抛出错误），则p2的状态是rejected，且p2的promiseValue就是这个错误对象。</li></ul></li><li>如果p1的状态是rejected，then()会去执行f_err，则p2的状态由f_err的返回值决定。 <ul><li>如果f_err返回值不是Promise对象，则p2的状态是resolved，且p2的promiseValue就是f_err函数的return值。</li><li>如果f_err返回值是一个Promise对象，则p2的状态及promiseValue以这个Promise对象为准。</li><li>如果f_err这个函数内部发生了错误（或者是用户主动抛出错误），则p2的状态是rejected，且p2的promiseValue就是这个错误对象。</li></ul></li></ul><h3 id="练习1" tabindex="-1">练习1 <a class="header-anchor" href="#练习1" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">(()</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(){}); </span><span style="color:#8B949E;">// p2也是一个promise对象。</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p1); </span><span style="color:#8B949E;">// pending</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p2); </span><span style="color:#8B949E;">// pending</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h3 id="练习2" tabindex="-1">练习2 <a class="header-anchor" href="#练习2" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">()});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">1</span></span>
<span class="line"><span style="color:#C9D1D9;">}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(){}); </span><span style="color:#8B949E;">// p2也是一个promise对象。</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p1);    </span><span style="color:#8B949E;">// resolved, undefined</span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p2); </span><span style="color:#8B949E;">// resolved, 1</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>特殊地，如果f_ok()中并没有return语句，则相当于是 return undefined。</p><h3 id="练习3" tabindex="-1">练习3 <a class="header-anchor" href="#练习3" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">()});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> temp </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">({a:</span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">}) }); </span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> temp;</span></span>
<span class="line"><span style="color:#C9D1D9;">}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(){}); </span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p2); </span><span style="color:#8B949E;">// resolved, {a:1}</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h3 id="练习4" tabindex="-1">练习4 <a class="header-anchor" href="#练习4" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">()});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"><span style="color:#C9D1D9;">  console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(abc);</span><span style="color:#8B949E;">// 这里故意犯错</span></span>
<span class="line"><span style="color:#C9D1D9;">}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(){}); </span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p2);</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="练习5" tabindex="-1">练习5 <a class="header-anchor" href="#练习5" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">100</span><span style="color:#C9D1D9;">)});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">errVal</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> temp </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">({b:errVal}) }); </span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> temp;</span></span>
<span class="line"><span style="color:#C9D1D9;">}); </span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p2);</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h3 id="练习6" tabindex="-1">练习6 <a class="header-anchor" href="#练习6" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{ </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">100</span><span style="color:#C9D1D9;">)});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_ok</span><span style="color:#C9D1D9;">(){</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">}, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">f_err</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">errVal</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#FF7B72;">throw</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">Error</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&quot;aaa&quot;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">}); </span></span>
<span class="line"><span style="color:#C9D1D9;">console.</span><span style="color:#D2A8FF;">dir</span><span style="color:#C9D1D9;">(p2)</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h2 id="catch的格式及用法" tabindex="-1">catch的格式及用法 <a class="header-anchor" href="#catch的格式及用法" aria-hidden="true">#</a></h2><p>catch 是 then(null, reject)的别名</p><h3 id="catch-的格式及用法" tabindex="-1">catch()的格式及用法 <a class="header-anchor" href="#catch-的格式及用法" aria-hidden="true">#</a></h3><p>Promise.prototype.catch 是 Promise.prototype.then(null, reject)的别名，用于指定当promise对象的状态从pending变成rejected的回调函数 。</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;s&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">});</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">p1.</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">  console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(err);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 与下面的代码等价</span></span>
<span class="line"><span style="color:#C9D1D9;">p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">null</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">  console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(err);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>单独使用catch没有什么意义，它一般与then一块使用。如下：</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">,</span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">)</span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;">{</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">result</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#8B949E;">// 如果promise对象的状态是resolved的，就会到这里来，并且result会接收promiseValue的值</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">  </span><span style="color:#8B949E;">// 如果promise对象的状态是rejected的，就会到这里来，并且err会接收promiseValue的值</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 上面的代码如何拆分来写的话，等价于：</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((resolve,reject){</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p1.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">result</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">});</span></span>
<span class="line"><span style="color:#FF7B72;">var</span><span style="color:#C9D1D9;"> p3 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> p2.</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h3 id="catch的返回值" tabindex="-1">catch的返回值 <a class="header-anchor" href="#catch的返回值" aria-hidden="true">#</a></h3><p>catch的返回值仍是一个promise对象，确定它的值的方式与then(null,(errVal)=&gt;{ })的方式一致。</p><h2 id="promise-链式调用" tabindex="-1">Promise-链式调用 <a class="header-anchor" href="#promise-链式调用" aria-hidden="true">#</a></h2><h3 id="目标-10" tabindex="-1">目标 <a class="header-anchor" href="#目标-10" aria-hidden="true">#</a></h3><p>掌握Promise的链式调用</p><h3 id="p-then-的返回值是一个新的promsie对象" tabindex="-1">p.then()的返回值是一个新的promsie对象 <a class="header-anchor" href="#p-then-的返回值是一个新的promsie对象" aria-hidden="true">#</a></h3><p>编写代码进行讲解</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功1&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功2&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">p.</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#8B949E;">// 如果return一个Promise对象,它的结果, 会被下个then接收</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h3 id="小结-8" tabindex="-1">小结 <a class="header-anchor" href="#小结-8" aria-hidden="true">#</a></h3><ol><li>then里return的Promise对象结果, 交到哪里执行? <details><summary>答案</summary><ul><li> 下一个then接收成功结果 </li></ul></details></li></ol><h2 id="promise-解决回调地狱" tabindex="-1">Promise-解决回调地狱 <a class="header-anchor" href="#promise-解决回调地狱" aria-hidden="true">#</a></h2><h3 id="目标-11" tabindex="-1">目标 <a class="header-anchor" href="#目标-11" aria-hidden="true">#</a></h3><p>使用Promise来解决回调地狱</p><h3 id="基础代码" tabindex="-1">基础代码 <a class="header-anchor" href="#基础代码" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 获取所有省市区数据, 随便获取</span></span>
<span class="line"><span style="color:#8B949E;">// 1. 获取所有省份列表</span></span>
<span class="line"><span style="color:#C9D1D9;">axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/province&#39;</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 2. 获取某个省, 对应的城市列表</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> pname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.data[</span><span style="color:#79C0FF;">5</span><span style="color:#C9D1D9;">];</span></span>
<span class="line"><span style="color:#C9D1D9;">    axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/city?pname=${</span><span style="color:#C9D1D9;">pname</span><span style="color:#A5D6FF;">}`</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 3. 获取某个市, 对应的地区列表</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> cname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.data[</span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">]</span></span>
<span class="line"><span style="color:#C9D1D9;">        axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/area?pname=${</span><span style="color:#C9D1D9;">pname</span><span style="color:#A5D6FF;">}&amp;cname=${</span><span style="color:#C9D1D9;">cname</span><span style="color:#A5D6FF;">}`</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">        })</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 上面的代码就出现了回调地狱</span></span>
<span class="line"><span style="color:#8B949E;">// 概念: 在回调函数内, 再嵌套回调函数, 一直嵌套下去形成了回调地狱</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h3 id="讲解-2" tabindex="-1">讲解 <a class="header-anchor" href="#讲解-2" aria-hidden="true">#</a></h3><ol><li>新建html文件, 用axios方法原地返回Promise对象特性</li><li>用.then()里return Promise对象结果会被链式调用下一个then接收特性</li></ol><blockquote><p>把回调函数嵌套的写法, 变成链式调用then的形式</p></blockquote><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 使用Promise的链式调用解决问题</span></span>
<span class="line"><span style="color:#8B949E;">// 前提: axios函数在原地返回的就是一个Promise对象</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> pname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#A5D6FF;">&#39;&#39;</span></span>
<span class="line"><span style="color:#C9D1D9;">axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/province&#39;</span><span style="color:#C9D1D9;">).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 2. 获取某个省, 对应的城市列表</span></span>
<span class="line"><span style="color:#C9D1D9;">    pname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.data[</span><span style="color:#79C0FF;">5</span><span style="color:#C9D1D9;">];</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/city?pname=${</span><span style="color:#C9D1D9;">pname</span><span style="color:#A5D6FF;">}`</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 3. 获取某个市, 对应的地区列表</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> cname </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.data[</span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">]</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> axios.</span><span style="color:#D2A8FF;">get</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">`http://ajax-api.itheima.net/api/area?pname=${</span><span style="color:#C9D1D9;">pname</span><span style="color:#A5D6FF;">}&amp;cname=${</span><span style="color:#C9D1D9;">cname</span><span style="color:#A5D6FF;">}`</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h3 id="小结-9" tabindex="-1">小结 <a class="header-anchor" href="#小结-9" aria-hidden="true">#</a></h3><ol><li>Promise是如何解决回调地狱的问题的? <details><summary>答案</summary><ul><li> 根据.then的链式调用把Promise对象串联起来 </li></ul></details></li></ol><h2 id="promise的静态方法-all" tabindex="-1">Promise的静态方法-all <a class="header-anchor" href="#promise的静态方法-all" aria-hidden="true">#</a></h2><h3 id="目标-12" tabindex="-1">目标 <a class="header-anchor" href="#目标-12" aria-hidden="true">#</a></h3><p>能说出Promise.all方法的作用</p><h3 id="promise的all方法语法" tabindex="-1">Promise的all方法语法 <a class="header-anchor" href="#promise的all方法语法" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">all</span><span style="color:#C9D1D9;">([promise对象1, promise对象2, </span><span style="color:#FF7B72;">...</span><span style="color:#C9D1D9;">]).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>特点: 返回最终结果是个数组, 值是按顺序对应小Promise对象的成功结果</p><p>注意: 如果有1个Promise失败, 则整个Promise对象则失败</p><p>作用: 合并多个Promise对象, 等待所有成功后, 返回结果</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 讲解Promise的all方法</span></span>
<span class="line"><span style="color:#8B949E;">// 静态(类)方法: 直接用Promise类来调用</span></span>
<span class="line"><span style="color:#8B949E;">// 1. Promise.all() </span></span>
<span class="line"><span style="color:#8B949E;">// 作用: 合并多个Promise对象, 等待所有成功后, 返回结果</span></span>
<span class="line"><span style="color:#8B949E;">// 语法: Promise.all([promise对象1, promise对象2, ...]).then()</span></span>
<span class="line"><span style="color:#8B949E;">// 特点: 返回最终结果是个数组, 值是按顺序对应小Promise对象的成功结果</span></span>
<span class="line"><span style="color:#8B949E;">// 注意: 如果有1个Promise失败, 则整个Promise对象则失败</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功1&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功2&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p3 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功3&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">all</span><span style="color:#C9D1D9;">([p1, p2, p3]).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br></div></div><h3 id="小结-10" tabindex="-1">小结 <a class="header-anchor" href="#小结-10" aria-hidden="true">#</a></h3><ol><li>Promise.all方法有什么作用? <details><summary>答案</summary><ul><li> 合并并发多个Promise对象, 等待所有人成功, 按顺序接收结果 </li></ul></details></li></ol><h2 id="promise的静态方法-race" tabindex="-1">Promise的静态方法-race <a class="header-anchor" href="#promise的静态方法-race" aria-hidden="true">#</a></h2><h3 id="目标-13" tabindex="-1">目标 <a class="header-anchor" href="#目标-13" aria-hidden="true">#</a></h3><p>能说出Promise.race方法的作用</p><h3 id="promise的race方法语法" tabindex="-1">Promise的race方法语法 <a class="header-anchor" href="#promise的race方法语法" aria-hidden="true">#</a></h3><div class="language-js line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki"><code><span class="line"><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">race</span><span style="color:#C9D1D9;">([promise对象1, promise对象2, </span><span style="color:#FF7B72;">...</span><span style="color:#C9D1D9;">]).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>作用: 发起并行多个Promise对象, 等待只要任何一个有结果(成功|失败), 返回结果执行then</p><p>特点: 返回第一个有结果的promise对象的结果</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#8B949E;">// 目标: 讲解Promise的race方法</span></span>
<span class="line"><span style="color:#8B949E;">// 静态(类)方法: 直接用Promise类来调用</span></span>
<span class="line"><span style="color:#8B949E;">// 1. Promise.race() - 赛跑机制</span></span>
<span class="line"><span style="color:#8B949E;">// 作用: 发起并行多个Promise对象, 等待只要任何一个有结果(成功|失败), 返回结果执行then</span></span>
<span class="line"><span style="color:#8B949E;">// 语法: Promise.race([promise对象1, promise对象2, ...]).then()</span></span>
<span class="line"><span style="color:#8B949E;">// 特点: 返回第一个有结果的promise对象的结果</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p1 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功1&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p2 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功2&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p3 </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#D2A8FF;">setTimeout</span><span style="color:#C9D1D9;">(() </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;成功3&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">    }, </span><span style="color:#79C0FF;">2000</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span>
<span class="line"><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">race</span><span style="color:#C9D1D9;">([p1, p2, p3]).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">race</span><span style="color:#C9D1D9;">([p1, p2, p3]).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h3 id="小结-11" tabindex="-1">小结 <a class="header-anchor" href="#小结-11" aria-hidden="true">#</a></h3><ol><li>Promise.race方法有什么作用? <details><summary>答案</summary><ul><li> 合并并发多个Promise对象, 接收最先成功的结果 </li></ul></details></li></ol><h2 id="promise的静态方法resolve和reject" tabindex="-1">Promise的静态方法resolve和reject <a class="header-anchor" href="#promise的静态方法resolve和reject" aria-hidden="true">#</a></h2><h3 id="目标-14" tabindex="-1">目标 <a class="header-anchor" href="#目标-14" aria-hidden="true">#</a></h3><p>能说出Promise的静态方法resolve和reject方法作用</p><h3 id="promise-resolve的作用" tabindex="-1">Promise.resolve的作用 <a class="header-anchor" href="#promise-resolve的作用" aria-hidden="true">#</a></h3><p>创建一个状态为resolved的promise对象，并指定其值。或者理解为：把值转成Promise对象，并设置状态和值。</p><h4 id="格式-1" tabindex="-1">格式 <a class="header-anchor" href="#格式-1" aria-hidden="true">#</a></h4><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">const</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">p</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(值)</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h3 id="promise-reject作用" tabindex="-1">Promise.reject作用 <a class="header-anchor" href="#promise-reject作用" aria-hidden="true">#</a></h3><p>创建一个状态为rejected的promise对象。</p><h4 id="格式-2" tabindex="-1">格式 <a class="header-anchor" href="#格式-2" aria-hidden="true">#</a></h4><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">const</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">p</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">(值)</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h3 id="小结-12" tabindex="-1">小结 <a class="header-anchor" href="#小结-12" aria-hidden="true">#</a></h3><ol><li>Promise.resolve和Promise.reject有什么作用? <details><summary>答案</summary><ul><li> 创建一个状态为resolved, rejected的promise对象，并指定其值 </li></ul></details></li></ol><h2 id="案例-封装ajax函数" tabindex="-1">案例-封装Ajax函数 <a class="header-anchor" href="#案例-封装ajax函数" aria-hidden="true">#</a></h2><h3 id="目标-15" tabindex="-1">目标 <a class="header-anchor" href="#目标-15" aria-hidden="true">#</a></h3><p>了解封装原生Ajax请求的代码</p><h3 id="讲解-3" tabindex="-1">讲解 <a class="header-anchor" href="#讲解-3" aria-hidden="true">#</a></h3><p>新建html文件, 封装itheimaAxios函数。</p><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">itheimaAxios</span><span style="color:#C9D1D9;">({ </span><span style="color:#FFA657;">url</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">method</span><span style="color:#C9D1D9;">}) {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 1. 外面需要Promise对象, 所以创建一个并返回</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">((</span><span style="color:#FFA657;">resolve</span><span style="color:#C9D1D9;">, </span><span style="color:#FFA657;">reject</span><span style="color:#C9D1D9;">) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 2. 解构配置对象参数使用</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> xhr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">new</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">XMLHttpRequest</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">open</span><span style="color:#C9D1D9;">(method, url)</span></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">send</span><span style="color:#C9D1D9;">()</span></span>
<span class="line"><span style="color:#C9D1D9;">        xhr.</span><span style="color:#D2A8FF;">addEventListener</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;load&#39;</span><span style="color:#C9D1D9;">, </span><span style="color:#FF7B72;">function</span><span style="color:#C9D1D9;"> () {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#FF7B72;">if</span><span style="color:#C9D1D9;">(xhr.status </span><span style="color:#FF7B72;">&gt;=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">200</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">&amp;&amp;</span><span style="color:#C9D1D9;"> xhr.status</span><span style="color:#FF7B72;">&lt;</span><span style="color:#79C0FF;">400</span><span style="color:#C9D1D9;">){</span></span>
<span class="line"><span style="color:#C9D1D9;">                </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> result </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">JSON</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">parse</span><span style="color:#C9D1D9;">(xhr.response)</span></span>
<span class="line"><span style="color:#C9D1D9;">                </span><span style="color:#D2A8FF;">resolve</span><span style="color:#C9D1D9;">(result)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">            } </span><span style="color:#FF7B72;">else</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">                </span><span style="color:#D2A8FF;">reject</span><span style="color:#C9D1D9;">({message: xhr.response})</span></span>
<span class="line"><span style="color:#C9D1D9;">            }</span></span>
<span class="line"><span style="color:#C9D1D9;">        })   </span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">}</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 测试</span></span>
<span class="line"><span style="color:#D2A8FF;">itheimaAxios</span><span style="color:#C9D1D9;">({</span></span>
<span class="line"><span style="color:#C9D1D9;">    url: </span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net/api/province&#39;</span><span style="color:#C9D1D9;">,</span></span>
<span class="line"><span style="color:#C9D1D9;">    method: </span><span style="color:#A5D6FF;">&#39;GET&#39;</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res)</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">catch</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">err</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">error</span><span style="color:#C9D1D9;">(err)</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br></div></div><h3 id="小结-13" tabindex="-1">小结 <a class="header-anchor" href="#小结-13" aria-hidden="true">#</a></h3><ol><li>promise的作用在于改写原来需要回调函数才实现的异步操作。</li></ol><h2 id="案例-分类导航" tabindex="-1">案例-分类导航 <a class="header-anchor" href="#案例-分类导航" aria-hidden="true">#</a></h2><h3 id="目标-16" tabindex="-1">目标 <a class="header-anchor" href="#目标-16" aria-hidden="true">#</a></h3><ul><li>完成分类导航案例 <img src="/tingweipeng/assets/1668096784395-de21bc92-b1e9-49d7-8d22-0b90a978858e.771495bb.gif" alt="分类效果.gif" data-fancybox="gallery"></li></ul><h3 id="讲解-4" tabindex="-1">讲解 <a class="header-anchor" href="#讲解-4" aria-hidden="true">#</a></h3><p>新建html, 在这个基础上编写</p><div class="language-html line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">html</span><pre class="shiki"><code><span class="line"><span style="color:#C9D1D9;">&lt;!</span><span style="color:#7EE787;">DOCTYPE</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">html</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">&lt;</span><span style="color:#7EE787;">html</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">lang</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;en&quot;</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">&lt;</span><span style="color:#7EE787;">head</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">meta</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">charset</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;UTF-8&quot;</span><span style="color:#C9D1D9;"> /&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">meta</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">http-equiv</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;X-UA-Compatible&quot;</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">content</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;IE=edge&quot;</span><span style="color:#C9D1D9;"> /&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">meta</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">name</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;viewport&quot;</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">content</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;width=device-width, initial-scale=1.0&quot;</span><span style="color:#C9D1D9;"> /&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">title</span><span style="color:#C9D1D9;">&gt;20.案例_分类导航&lt;/</span><span style="color:#7EE787;">title</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">style</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#7EE787;">*</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">margin</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">padding</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">box-sizing</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">border-box</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#7EE787;">a</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">text-decoration</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">none</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">color</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">#333</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#7EE787;">ul</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">list-style</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">none</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.container</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">width</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">980</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">margin</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">auto</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.top</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">display</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">flex</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">width</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">100</span><span style="color:#FF7B72;">%</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">height</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">80</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">align-items</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">center</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">justify-content</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">space-around</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">position</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">relative</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.top</span><span style="color:#FF7B72;">&gt;</span><span style="color:#7EE787;">li</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">text-align</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">center</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.top</span><span style="color:#FF7B72;">&gt;</span><span style="color:#7EE787;">li</span><span style="color:#FF7B72;">&gt;</span><span style="color:#7EE787;">a</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">border-bottom</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">1</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">solid</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">transparent</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.top</span><span style="color:#FF7B72;">&gt;</span><span style="color:#7EE787;">li</span><span style="color:#79C0FF;">:hover</span><span style="color:#FF7B72;">&gt;</span><span style="color:#7EE787;">a</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">border-color</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">#27ba9b</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">color</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">#27ba9b</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.top</span><span style="color:#FF7B72;">&gt;</span><span style="color:#7EE787;">li</span><span style="color:#79C0FF;">:hover</span><span style="color:#FF7B72;">&gt;</span><span style="color:#79C0FF;">.sub</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">opacity</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">transform</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">scale</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">, </span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.sub</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">position</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">absolute</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">left</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">top</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">80</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">box-shadow</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">10</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">rgba</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">, </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">, </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">, </span><span style="color:#79C0FF;">0.1</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">width</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">100</span><span style="color:#FF7B72;">%</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">display</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">flex</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">align-items</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">center</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">height</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">100</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">opacity</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">transform</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">scale</span><span style="color:#C9D1D9;">(</span><span style="color:#79C0FF;">1</span><span style="color:#C9D1D9;">, </span><span style="color:#79C0FF;">0</span><span style="color:#C9D1D9;">);</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">transform-origin</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">top</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">center</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">transition</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">all</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">0.3</span><span style="color:#FF7B72;">s</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">.1</span><span style="color:#FF7B72;">s</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.sub</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">li</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">width</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">120</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">text-align</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">center</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.sub</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">li</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">a</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">display</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">block</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">font-size</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">14</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">padding-top</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">8</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.sub</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">li</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">a</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">span</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">display</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">block</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#79C0FF;">.sub</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">li</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">a</span><span style="color:#C9D1D9;"> </span><span style="color:#7EE787;">img</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">width</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">60</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">height</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">60</span><span style="color:#FF7B72;">px</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#79C0FF;">vertical-align</span><span style="color:#C9D1D9;">: </span><span style="color:#79C0FF;">middle</span><span style="color:#C9D1D9;">;</span></span>
<span class="line"><span style="color:#C9D1D9;">        }</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;/</span><span style="color:#7EE787;">style</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">&lt;/</span><span style="color:#7EE787;">head</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">&lt;</span><span style="color:#7EE787;">body</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">div</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">class</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;container&quot;</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">        &lt;</span><span style="color:#7EE787;">ul</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">class</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;top&quot;</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#8B949E;">&lt;!-- &lt;li&gt;</span></span>
<span class="line"><span style="color:#8B949E;">        &lt;a href=&quot;javascript:;&quot;&gt;首页&lt;/a&gt;</span></span>
<span class="line"><span style="color:#8B949E;">        &lt;ul class=&quot;sub&quot;&gt;</span></span>
<span class="line"><span style="color:#8B949E;">          &lt;li&gt;</span></span>
<span class="line"><span style="color:#8B949E;">            &lt;a href=&quot;javascript:;&quot;&gt;</span></span>
<span class="line"><span style="color:#8B949E;">              &lt;span&gt;砂锅厨具&lt;/span&gt;</span></span>
<span class="line"><span style="color:#8B949E;">              &lt;img src=&quot;https://yanxuan.nosdn.127.net/3102b963e7a3c74b9d2ae90e4380da65.png?quality=95&amp;imageView&quot; alt=&quot;&quot;&gt;</span></span>
<span class="line"><span style="color:#8B949E;">            &lt;/a&gt;</span></span>
<span class="line"><span style="color:#8B949E;">          &lt;/li&gt;</span></span>
<span class="line"><span style="color:#8B949E;">        &lt;/ul&gt;</span></span>
<span class="line"><span style="color:#8B949E;">      &lt;/li&gt; --&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">        &lt;/</span><span style="color:#7EE787;">ul</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;/</span><span style="color:#7EE787;">div</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;"> </span><span style="color:#79C0FF;">src</span><span style="color:#C9D1D9;">=</span><span style="color:#A5D6FF;">&quot;https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js&quot;</span><span style="color:#C9D1D9;">&gt;&lt;/</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span></span>
<span class="line"><span style="color:#C9D1D9;">    &lt;/</span><span style="color:#7EE787;">script</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"><span style="color:#C9D1D9;">&lt;/</span><span style="color:#7EE787;">body</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">&lt;/</span><span style="color:#7EE787;">html</span><span style="color:#C9D1D9;">&gt;</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br><span class="line-number">85</span><br><span class="line-number">86</span><br><span class="line-number">87</span><br><span class="line-number">88</span><br><span class="line-number">89</span><br><span class="line-number">90</span><br><span class="line-number">91</span><br><span class="line-number">92</span><br><span class="line-number">93</span><br><span class="line-number">94</span><br><span class="line-number">95</span><br><span class="line-number">96</span><br><span class="line-number">97</span><br><span class="line-number">98</span><br><span class="line-number">99</span><br><span class="line-number">100</span><br><span class="line-number">101</span><br><span class="line-number">102</span><br><span class="line-number">103</span><br><span class="line-number">104</span><br><span class="line-number">105</span><br><span class="line-number">106</span><br><span class="line-number">107</span><br><span class="line-number">108</span><br><span class="line-number">109</span><br><span class="line-number">110</span><br><span class="line-number">111</span><br><span class="line-number">112</span><br><span class="line-number">113</span><br><span class="line-number">114</span><br><span class="line-number">115</span><br><span class="line-number">116</span><br><span class="line-number">117</span><br></div></div><h3 id="分析思路和数据-进行铺设" tabindex="-1">分析思路和数据, 进行铺设 <a class="header-anchor" href="#分析思路和数据-进行铺设" aria-hidden="true">#</a></h3><div class="language-javascript line-numbers-mode"><button title="Copy Code" class="copy"></button><span class="lang">javascript</span><pre class="shiki"><code><span class="line"><span style="color:#C9D1D9;">axios.defaults.baseURL </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#A5D6FF;">&#39;http://ajax-api.itheima.net&#39;</span></span>
<span class="line"><span style="color:#8B949E;">// 1. 先准备一套标签和样式 (md复制-读一读对应上)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 获取铺设前, 在读标签发现不简单</span></span>
<span class="line"><span style="color:#8B949E;">// 正常思想1: 鼠标移入事件, 再获取二级数据并铺设</span></span>
<span class="line"><span style="color:#8B949E;">// 现在思想2: 它是移入直接css方式让二级数据div直接显示(意思就是二级所有的div要提前铺设好)</span></span>
<span class="line"><span style="color:#8B949E;">// 思想1, 前面我们练习过, 不难, 思想2, 我们着重讲解下</span></span>
<span class="line"></span>
<span class="line"><span style="color:#8B949E;">// 2. 先获取一级分类数据列表</span></span>
<span class="line"><span style="color:#D2A8FF;">axios</span><span style="color:#C9D1D9;">({</span></span>
<span class="line"><span style="color:#C9D1D9;">    url: </span><span style="color:#A5D6FF;">&#39;/api/category/top&#39;</span></span>
<span class="line"><span style="color:#C9D1D9;">}).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(({ </span><span style="color:#FFA657;">data</span><span style="color:#C9D1D9;">: </span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> }) </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// axios()在原地返回Promise对象(此Promise对象内包裹一个原生Ajax请求)</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// axios它自己封装了一个结果对象, 并把后端返回的数据挂载到data属性下</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 所以: 我想让res的值直接是后端返回的数据</span></span>
<span class="line"><span style="color:#C9D1D9;">    console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res); </span><span style="color:#8B949E;">// { data: [{一级分类对象}, {一级分类对象}] }</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> secondPromiseArr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.data.</span><span style="color:#D2A8FF;">map</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">obj</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 3. 遍历每个一级分类对象, 再请求下属的二级分类列表</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> p </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> </span><span style="color:#D2A8FF;">axios</span><span style="color:#C9D1D9;">({</span></span>
<span class="line"><span style="color:#C9D1D9;">            url: </span><span style="color:#A5D6FF;">&#39;/api/category/sub&#39;</span><span style="color:#C9D1D9;">,</span></span>
<span class="line"><span style="color:#C9D1D9;">            params: {</span></span>
<span class="line"><span style="color:#C9D1D9;">                id: obj.id </span><span style="color:#8B949E;">// 一级id</span></span>
<span class="line"><span style="color:#C9D1D9;">            }</span></span>
<span class="line"><span style="color:#C9D1D9;">        })</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 问题: 循环很快, 二级分类的多个请求并行, 谁先回来不一定</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 解决: 想要按顺序来, 使用Promise.all, 先返回并形成一个Promise数组</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> p</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// secondPromiseArr结果: [ 小Promise对象(负责请求二级分类), 小Promise对象 ]</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#8B949E;">// 5. 把二级分类请求Promise对象, 合并成一个大的Promise对象</span></span>
<span class="line"><span style="color:#C9D1D9;">    </span><span style="color:#79C0FF;">Promise</span><span style="color:#C9D1D9;">.</span><span style="color:#D2A8FF;">all</span><span style="color:#C9D1D9;">(secondPromiseArr).</span><span style="color:#D2A8FF;">then</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">res</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> {</span></span>
<span class="line"><span style="color:#C9D1D9;">        console.</span><span style="color:#D2A8FF;">log</span><span style="color:#C9D1D9;">(res);</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// 6. 有了最终的数据, 循环产生一级和二级的标签结构并铺设到页面上</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#8B949E;">// res: [ 二级分类列表axios结果对象, 二级分类列表axios结果对象  ] (9个)</span></span>
<span class="line"><span style="color:#C9D1D9;">        </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> allLiStr </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> res.</span><span style="color:#D2A8FF;">map</span><span style="color:#C9D1D9;">(</span><span style="color:#FFA657;">result</span><span style="color:#C9D1D9;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#C9D1D9;"> { </span><span style="color:#8B949E;">// result: 是二级分类列表axios结果对象</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#FF7B72;">let</span><span style="color:#C9D1D9;"> obj </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> result.data.data </span><span style="color:#8B949E;">// 二级分类数据对象</span></span>
<span class="line"><span style="color:#C9D1D9;">            </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> </span><span style="color:#A5D6FF;">`&lt;li&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                        &lt;a href=&quot;javascript:;&quot;&gt;${</span><span style="color:#C9D1D9;">obj</span><span style="color:#A5D6FF;">.</span><span style="color:#C9D1D9;">name</span><span style="color:#A5D6FF;">}&lt;/a&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                        &lt;ul class=&quot;sub&quot;&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                            ${</span><span style="color:#C9D1D9;">obj</span><span style="color:#A5D6FF;">.</span><span style="color:#C9D1D9;">children</span><span style="color:#A5D6FF;">.</span><span style="color:#D2A8FF;">map</span><span style="color:#A5D6FF;">(</span><span style="color:#79C0FF;">item</span><span style="color:#A5D6FF;"> </span><span style="color:#FF7B72;">=&gt;</span><span style="color:#A5D6FF;"> </span><span style="color:#C9D1D9;">{</span></span>
<span class="line"><span style="color:#C9D1D9;">                                </span><span style="color:#FF7B72;">return</span><span style="color:#C9D1D9;"> </span><span style="color:#A5D6FF;">`&lt;li&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                                            &lt;a href=&quot;javascript:;&quot;&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                                                &lt;span&gt;${</span><span style="color:#C9D1D9;">item</span><span style="color:#A5D6FF;">.</span><span style="color:#C9D1D9;">name</span><span style="color:#A5D6FF;">}&lt;/span&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                                                &lt;img src=&quot;${</span><span style="color:#C9D1D9;">item</span><span style="color:#A5D6FF;">.</span><span style="color:#C9D1D9;">picture</span><span style="color:#A5D6FF;">}&quot; alt=&quot;&quot;&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                                            &lt;/a&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                                        &lt;/li&gt;`</span></span>
<span class="line"><span style="color:#C9D1D9;">                            }</span><span style="color:#A5D6FF;">).</span><span style="color:#D2A8FF;">join</span><span style="color:#A5D6FF;">(</span><span style="color:#A5D6FF;">&#39;&#39;</span><span style="color:#A5D6FF;">)</span><span style="color:#A5D6FF;">}</span></span>
<span class="line"><span style="color:#A5D6FF;">                        &lt;/ul&gt;</span></span>
<span class="line"><span style="color:#A5D6FF;">                    &lt;/li&gt;`</span></span>
<span class="line"><span style="color:#C9D1D9;">        }).</span><span style="color:#D2A8FF;">join</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;&#39;</span><span style="color:#C9D1D9;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C9D1D9;">        document.</span><span style="color:#D2A8FF;">querySelector</span><span style="color:#C9D1D9;">(</span><span style="color:#A5D6FF;">&#39;.top&#39;</span><span style="color:#C9D1D9;">).innerHTML </span><span style="color:#FF7B72;">=</span><span style="color:#C9D1D9;"> allLiStr</span></span>
<span class="line"><span style="color:#C9D1D9;">    })</span></span>
<span class="line"><span style="color:#C9D1D9;">})</span></span>
<span class="line"></span></code></pre><div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br></div></div><h3 id="小结-14" tabindex="-1">小结 <a class="header-anchor" href="#小结-14" aria-hidden="true">#</a></h3><ol><li>如何同时发送多个请求, 并按顺序接收结果? <details><summary>答案</summary><ul><li> 使用Promise.all方法 </li></ul></details></li></ol><h2 id="今日作业-必完成" tabindex="-1">今日作业(必完成) <a class="header-anchor" href="#今日作业-必完成" aria-hidden="true">#</a></h2><h3 id="作业1-整理笔记" tabindex="-1">作业1-整理笔记 <a class="header-anchor" href="#作业1-整理笔记" aria-hidden="true">#</a></h3><ol><li>把今天知识点梳理一遍, 记好笔记</li></ol><h3 id="作业2-案例" tabindex="-1">作业2-案例 <a class="header-anchor" href="#作业2-案例" aria-hidden="true">#</a></h3><ol><li>课上案例分类导航, 至少再写一遍</li></ol><h3 id="作业3-答题" tabindex="-1">作业3-答题 <a class="header-anchor" href="#作业3-答题" aria-hidden="true">#</a></h3><ol><li>10道选择题(祝你得100分): <a href="https://ks.wjx.top/vm/YVNglOg.aspx" target="_blank" rel="noreferrer">https://ks.wjx.top/vm/YVNglOg.aspx</a></li></ol><h3 id="作业4-完成方法实现" tabindex="-1">作业4-完成方法实现 <a class="header-anchor" href="#作业4-完成方法实现" aria-hidden="true">#</a></h3><ol><li>自己实现forEach和map方法内部实现基本过程(可以百度)</li></ol><h3 id="作业5-每日反馈" tabindex="-1">作业5-每日反馈 <a class="header-anchor" href="#作业5-每日反馈" aria-hidden="true">#</a></h3><ol><li>关注微信群的每日反馈</li></ol><h2 id="面试题-自行扩展" tabindex="-1">面试题(自行扩展) <a class="header-anchor" href="#面试题-自行扩展" aria-hidden="true">#</a></h2><ol><li>Promise的使用场景? <a href="https://lamphc.github.io/fe-up/#/es6/promise" target="_blank" rel="noreferrer">参考文档</a></li></ol><h2 id="参考文档" tabindex="-1">参考文档 <a class="header-anchor" href="#参考文档" aria-hidden="true">#</a></h2><ol><li><a href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/AJAX/Getting_Started" target="_blank" rel="noreferrer">Ajax原生-mdn</a></li><li><a href="https://developer.mozilla.org/zh-CN/docs/Glossary/JSON" target="_blank" rel="noreferrer">JSON-mdn</a></li><li><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests" target="_blank" rel="noreferrer">同步异步-mdn</a></li><li><a href="https://developer.mozilla.org/zh-CN/docs/Glossary/Callback_function" target="_blank" rel="noreferrer">回调函数-mdn</a></li><li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noreferrer">Promise-mdn</a></li></ol></div></div></main><!--[--><!--]--><footer class="VPDocFooter" data-v-cfb513e0 data-v-21f75714><!----><div class="prev-next" data-v-21f75714><div class="pager" data-v-21f75714><a class="pager-link prev" href="/tingweipeng/ajax/day02.html" data-v-21f75714><span class="desc" data-v-21f75714>Previous page</span><span class="title" data-v-21f75714>02-表单提交</span></a></div><div class="has-prev pager" data-v-21f75714><a class="pager-link next" href="/tingweipeng/ajax/day04.html" data-v-21f75714><span class="desc" data-v-21f75714>Next page</span><span class="title" data-v-21f75714>04-异步编程和事件循环</span></a></div></div></footer><!--[--><!--]--></div></div></div></div></div><!----><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"ajax_day02.md\":\"e35eca52\",\"ajax_day03.md\":\"585e2c65\",\"ajax_day04.md\":\"0ca703d2\",\"ajax_index.md\":\"2b437449\",\"index.md\":\"ff5d4089\",\"js进阶_day02.md\":\"24ed742a\",\"js进阶_day03.md\":\"f0d3d414\",\"js进阶_day04.md\":\"d30bb382\",\"js进阶_index.md\":\"c6d77850\",\"vue基础_day02.md\":\"5f8c856e\",\"vue基础_day03.md\":\"7cd8d83f\",\"vue基础_index.md\":\"05339e1f\",\"webapis_day02.md\":\"0ca07905\",\"webapis_day03.md\":\"80c6b805\",\"webapis_day04.md\":\"6159ddb6\",\"webapis_day05.md\":\"fdfba8b3\",\"webapis_day06.md\":\"aaece170\",\"webapis_index.md\":\"8bdb89a3\"}")</script>
    <script type="module" async src="/tingweipeng/assets/app.bfa3a24a.js"></script>
    
  </body>
</html>